package com.spit.fammo.viewmodel

import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.databinding.ObservableBoolean
import androidx.lifecycle.MutableLiveData
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ThreadUtils
import com.blankj.utilcode.util.ToastUtils
import com.gg.reader.api.dal.GClient
import com.gg.reader.api.dal.HandlerDebugLog
import com.gg.reader.api.dal.HandlerTagEpcLog
import com.gg.reader.api.dal.HandlerTagEpcOver
import com.gg.reader.api.protocol.gx.EnumG
import com.gg.reader.api.protocol.gx.MsgAppGetBaseVersion
import com.gg.reader.api.protocol.gx.MsgBaseGetTagLog
import com.gg.reader.api.protocol.gx.MsgBaseInventoryEpc
import com.gg.reader.api.protocol.gx.MsgBaseSetBaseband
import com.gg.reader.api.protocol.gx.MsgBaseSetPower
import com.gg.reader.api.protocol.gx.MsgBaseStop
import com.gg.reader.api.protocol.gx.ParamEpcFilter
import com.gg.reader.api.protocol.gx.ParamEpcReadTid
import com.gg.reader.api.utils.StringUtils
import com.spit.fammo.R
import com.spit.fammo.bean.AppRoomDataBase
import com.spit.fammo.bean.DataBean
import com.spit.fammo.ext.DOWNLOAD_PAGE
import com.spit.fammo.ext.LOG_OUT_PAGE
import com.spit.fammo.ext.POWER_SETTING_PAGE
import com.spit.fammo.ext.STOCK_TAKE_LIST_PAGE
import com.spit.fammo.ext.UPLOAD_PAGE
import com.spit.fammo.keyctrl.GlobalClient
import com.spit.fammo.keyctrl.InventoryInfo
import com.spit.fammo.service.PowerUtil
import me.hgj.jetpackmvvm.base.appContext
import me.hgj.jetpackmvvm.base.viewmodel.BaseViewModel
import me.hgj.jetpackmvvm.callback.databind.BooleanObservableField
import me.hgj.jetpackmvvm.callback.databind.IntObservableField
import java.util.Date
import java.util.Hashtable
import java.util.Timer
import java.util.TimerTask
import java.util.concurrent.ConcurrentLinkedQueue


/**
 * @Author nike
 * @Date 2023/7/24 15:06
 * @Description
 */
class RfidModel : BaseViewModel() {

    var rfidData: MutableLiveData<InventoryInfo> = MutableLiveData()
    var rfidListData: MutableLiveData<List<InventoryInfo>> = MutableLiveData()

    var isOpen: MutableLiveData<Boolean> = MutableLiveData()

    var longPressNext = BooleanObservableField()

    var KEYCODE_MEDIA_NEXT = IntObservableField(619)

    var isSearchOpen: MutableLiveData<String> = MutableLiveData()

    val configDao = AppRoomDataBase.get().getConfigDao()

    var epcData: MutableLiveData<InventoryInfo> = MutableLiveData()
    var epcListData: MutableLiveData<List<InventoryInfo>> = MutableLiveData()

    var scanData: MutableLiveData<InventoryInfo> = MutableLiveData()

    var client: GClient = GlobalClient.getClient()

    var tagFindParam: String? = null

    var mainDrawerListBean: MutableLiveData<ArrayList<DataBean>> = MutableLiveData()
    var mainDrawerUploadNum: MutableLiveData<Int> = MutableLiveData()

    private var timer: Timer? = null

    var isScan = BooleanObservableField(false)

    //计算时间条数
    private var mStatHandler = Handler()
    var mTotalCount = 0
    private var mStartTime: Date? = null
     fun readTimer() {
        if (timer != null) {
            timer!!.cancel()
            timer = null
        }
         timer = Timer()
         val timerTask: TimerTask = object : TimerTask() {
             override fun run() {
                 ThreadUtils.runOnUiThread { mStatHandler.post(r) }
             }
         }
         timer!!.schedule(timerTask, 1000, 1000)
         mStartTime = Date()
         mTotalCount = 0
    }
    private fun padLeft(c: Char, length: Long, content: String): String? {
        var str = ""
        val cl: Long = 0
        var cs = ""
        if (content.length > length) {
            str = content
        } else {
            for (i in 0 until length - content.length) {
                cs = cs + c
            }
        }
        str = cs + content
        return str
    }
    private val r = Runnable {
        val nowTime = Date()
        val diff = nowTime.time - mStartTime!!.time
        if (diff > 0) {
            val h = diff / 3600000
            val m = diff % 3600000 / 60000
            val s = diff % 60000 / 1000
            LogUtils.e(
                "总次数：" + padLeft(' ', 5, "" + mTotalCount),
                "扫描时间：" + (if (h < 10) "0$h" else h) + ":" + (if (m < 10) "0$m" else m) + ":" + if (s < 10) "0$s" else s
            )
        }
    }


    fun config(){
        var configBean = configDao.findFirst()
        val msgBaseSetPower = MsgBaseSetPower()
        val hashtable = Hashtable<Int, Int>()
//        hashtable[1] = 33
        hashtable[1] = configBean.power
        msgBaseSetPower.setDicPower(hashtable)

        client.sendSynMsg(msgBaseSetPower)
        if (!msgBaseSetPower.rtMsg.contains("Success")){
            LogUtils.e("天线功率设置失败")
        }

        val msgBaseGetTagLog = MsgBaseGetTagLog()
        msgBaseGetTagLog.repeatedTime = 1000
        client.sendSynMsg(msgBaseGetTagLog)
        if (!msgBaseGetTagLog.rtMsg.contains("Success")){
            LogUtils.e("过滤秒数设置失败")
        }

        val msgBaseSetBaseband = MsgBaseSetBaseband()
        msgBaseSetBaseband.setBaseSpeed(configBean.speed)
        msgBaseSetBaseband.setSession(configBean.session)
        msgBaseSetBaseband.setqValue(configBean.qlabel)
        msgBaseSetBaseband.setInventoryFlag(configBean.inventoryFlag)

        //基带速度
//        msgBaseSetBaseband.setBaseSpeed(3)
//        msgBaseSetBaseband.setSession(0)
//        msgBaseSetBaseband.setqValue(4)
//        msgBaseSetBaseband.setInventoryFlag(2)

        LogUtils.e(
            "功率${configBean.power}",
            "基带速率${configBean.speed}",
            "session${configBean.session}",
            "标签模式${configBean.qlabel}",
            "盘存模式${configBean.inventoryFlag}",
        )

        client.sendSynMsg(msgBaseSetBaseband)
        if (!msgBaseSetBaseband.rtMsg.contains("Success")){
            LogUtils.e("标签模式设置失败")
        }
    }

    var initConn = object : ObservableBoolean(){
        override fun get(): Boolean {
            PowerUtil.power("1")
            val baudRateList = intArrayOf(460800, 115200)
            for (i in baudRateList) {
                val b: Boolean = return if(openReader(i.toString() + "")){
                    config()

                    val getBaseVersion = MsgAppGetBaseVersion()
                    client.sendSynMsg(getBaseVersion)
                    LogUtils.e(
                        "RFID模块连接成功",
                        getBaseVersion.baseVersions
                    )

                    true
                }else{
                    LogUtils.e("RFID模块连接失败")
                    false
                }
                if (b) {
                    break
                }
            }
            return false
        }
    }

    private fun initRfid() {
        PowerUtil.power("1")
        val baudRateList = intArrayOf(460800, 115200)
        for (i in baudRateList) {
            val b: Boolean = openReader(i.toString() + "")
            if (b) {
                break
            }
        }
    }

    private fun openReader(baudRate: String): Boolean {
        if (client.openAndroidSerial("/dev/ttyS3:$baudRate", 0)) {
            val stop = MsgBaseStop()
            client.sendSynMsg(stop)
            if (stop.rtCode == 0.toByte()) {
                return true
            } else {
                client.close()
                return false
            }
        } else {
            ToastUtils.showShort("打開串口失敗")
        }
        return false
    }

    val handler = Handler(Looper.getMainLooper())
    fun startJob() {
        handler.post(runnable)
    }

    // 停止定时任务
    fun cancelJob() {
        handler?.removeCallbacks(runnable)
    }
    val listInfo = ConcurrentLinkedQueue<InventoryInfo>()

    val runnable = object : Runnable {
        override fun run() {
            // 线程安全地获取数据列表
            val list = synchronized(listInfo) {
                val temp = listInfo.toList() // 创建列表的副本，避免直接修改原始列表
                listInfo.clear() // 清空原始列表
                temp
            }
            if (list.isNotEmpty()) {
                rfidListData.postValue(list)
            }
            handler.postDelayed(this, 1000)
        }
    }

    //EPC 来源
    fun onTagCallback(){
        client.onTagEpcLog = HandlerTagEpcLog { s, logBaseEpcInfo ->
            if (logBaseEpcInfo.result == 0) {
                var info = InventoryInfo()
                info.TagId = logBaseEpcInfo.epc
                info.Rssi = logBaseEpcInfo.rssi.toString()
                if (!info.TagId.isNullOrEmpty()) {
                    if (info.TagId.contains(" ")) {
                        info.TagId = info.TagId.replace(" ", "")
                    }
                    Log.e("", info.TagId)
                    listInfo.add(info)
                    mTotalCount += 1

                    if (tagFindParam != null){//判断是否搜索
                        rfidData.postValue(info)
                    }
                }
            }
        }
        client.onTagEpcOver = HandlerTagEpcOver { s, logBaseEpcOver ->
            Log.e("失败LogBaseEpcOver", logBaseEpcOver.rtMsg)
        }
        client.debugLog = object : HandlerDebugLog() {
            override fun sendDebugLog(s: String) {
                Log.e("失败sendDebugLog", s)
            }

            override fun receiveDebugLog(s: String) {
                Log.e("失败receiveDebugLog", s)
            }

            override fun crcErrorLog(s: String) {
                Log.e("失败crcErrorLog", s)
            }
        }
    }

   /* var handler: Handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                1 -> {
                    LogUtils.e("哈哈哈" + dataQueue.size)
                    dataQueue.clear()
                }
            }
        }
    }*/


    fun onStart(content: String?){
        client.sendUnsynMsg(MsgBaseStop())
        val msg = MsgBaseInventoryEpc()
        msg.antennaEnable = EnumG.AntennaNo_1
        msg.inventoryMode = EnumG.InventoryMode_Inventory
        //TID  mode 0自适应 1定长   len默认6
        msg.readTid = ParamEpcReadTid(0, 6)

        //是否匹配 0无 1EPC 2TID 3用户区
        var area = 1
        if (area != 0 && !StringUtils.isNullOfEmpty(content)) {
            tagFindParam = content
            val filter = ParamEpcFilter()
            filter.area = area
            filter.bitStart = if (area == 1) 32 else 0
            filter.bitLength = content!!.length * 4
            filter.hexData = content
            msg.filter = filter
        }
        client.sendSynMsg(msg)
        if (msg.rtCode.toInt() == 0) {
            readTimer()
        }
        onTagCallback()
    }

    fun onClose(){
        tagFindParam = null
        val stop = MsgBaseStop()
        client.sendSynMsg(stop)
        if (timer != null) {
            timer!!.cancel()
            timer = null
        }
        mStatHandler.post(r)
//        PowerUtil.power("0")
        if (client != null){
//            client.close()
        }
        LogUtils.e("断开连接")
    }

    fun onMainDrawerRequest() {
        val listBean: ArrayList<DataBean> by lazy {
            val titlesAndTypes = arrayOf(
//                Pair(R.string.search, 0),
//                Pair(R.string.registration, 1),
//                Pair(R.string.borrow, 2),
//                Pair(R.string.return_string, 3),
//                Pair(R.string.stock_take, 4),
//                Pair(R.string.disposal, 5),
//                Pair(R.string.download, 6),
//                Pair(R.string.upload, 7),
//                Pair(R.string.home_settings, 8),
//                Pair(R.string.logout, 9),
                Pair(R.string.stock_take, STOCK_TAKE_LIST_PAGE),
                Pair(R.string.download, DOWNLOAD_PAGE),
                Pair(R.string.upload, UPLOAD_PAGE),
                Pair(R.string.home_settings, POWER_SETTING_PAGE),
                Pair(R.string.logout, LOG_OUT_PAGE),
            )
            titlesAndTypes.map { (titleRes, type) ->
                DataBean(
                    Title = appContext.getString(titleRes),
                    Type = type,
                    num = 0
                )
            }.toCollection(ArrayList())
        }
        mainDrawerListBean.value = listBean
    }

}